#pragma once

namespace AVUI {

typedef ItemStructList< TRefCountedPtr<ResourceDictionary> > ResourceDictionaryList;

struct ResourcesChangeInfo
{
public:
#pragma region Internal Methods
    ResourcesChangeInfo();
    ResourcesChangeInfo(Object* pKey);
    ResourcesChangeInfo(ResourceDictionary* pOldDictionary, ResourceDictionary* pNewDictionary);
    ResourcesChangeInfo(ResourceDictionaryList* oldDictionaries, ResourceDictionaryList* newDictionaries, bool isStyleResourcesChange, bool isTemplateResourcesChange, DependencyObject* pContainer);
    bool Contains(Object* pKey, bool isImplicitStyleKey) const;
#pragma endregion Internal Methods

private:
#pragma region Private Flags

    class PrivateFlags
    {
    public:
        enum Enum
        {
            IsCatastrophicDictionaryChange = 0x20,
            IsStyleResourceChange = 4,
            IsSysColorsOrSettingsChange = 0x10,
            IsTemplateResourceChange = 8,
            IsThemeChange = 1,
            IsTreeChange = 2
        };
    };

#pragma endregion Private Flags

public:

#pragma region Internal Properties
    static ResourcesChangeInfo get_CatastrophicDictionaryChangeInfo()
    {
        ResourcesChangeInfo info;
        info.set_IsCatastrophicDictionaryChange(true);
        return info;
    }

    DependencyObject* get_Container() const { return m_pContainer; }

    bool get_IsCatastrophicDictionaryChange() const { return ReadPrivateFlag(PrivateFlags::IsCatastrophicDictionaryChange); }
    void set_IsCatastrophicDictionaryChange(bool value) { WritePrivateFlag(PrivateFlags::IsCatastrophicDictionaryChange, value); }

    bool get_IsResourceAddOperation() const;

    bool get_IsStyleResourcesChange() const { return ReadPrivateFlag(PrivateFlags::IsStyleResourceChange); }
    void set_IsStyleResourcesChange(bool value) { WritePrivateFlag(PrivateFlags::IsStyleResourceChange, value); }

    bool get_IsSysColorsOrSettingsChange() const { return ReadPrivateFlag(PrivateFlags::IsSysColorsOrSettingsChange); }
    void set_IsSysColorsOrSettingsChange(bool value) { WritePrivateFlag(PrivateFlags::IsSysColorsOrSettingsChange, value); }

    bool get_IsTemplateResourcesChange() const { return ReadPrivateFlag(PrivateFlags::IsTemplateResourceChange); }
    void set_IsTemplateResourcesChange(bool value) { WritePrivateFlag(PrivateFlags::IsTemplateResourceChange, value); }

    bool get_IsThemeChange() const { return ReadPrivateFlag(PrivateFlags::IsThemeChange); }
    void set_IsThemeChange(bool value) { WritePrivateFlag(PrivateFlags::IsThemeChange, value); }

    bool get_IsTreeChange() const { return ReadPrivateFlag(PrivateFlags::IsTreeChange); }
    void set_IsTreeChange(bool value) { WritePrivateFlag(PrivateFlags::IsTreeChange, value); }

    static ResourcesChangeInfo get_SysColorsOrSettingsChangeInfo()
    {
        ResourcesChangeInfo info;
        info.set_IsSysColorsOrSettingsChange(true);
        return info;
    }

    static ResourcesChangeInfo get_ThemeChangeInfo()
    {
        ResourcesChangeInfo info;
        info.set_IsThemeChange(true);
        return info;
    }

    static ResourcesChangeInfo get_TreeChangeInfo()
    {
        ResourcesChangeInfo info;
        info.set_IsTreeChange(true);
        return info;
    }

#pragma endregion Internal Properties

#pragma region Private Methods

    bool ReadPrivateFlag(PrivateFlags::Enum bit) const
    {
        return (((unsigned char) (m_flags & bit)) != 0);
    }

    void WritePrivateFlag(PrivateFlags::Enum bit, bool value)
    {
        if (value)
        {
            m_flags = m_flags | bit;
        }
        else
        {
            m_flags = (m_flags & ~bit);
        }
    }

#pragma endregion Private Methods

#pragma region Private Fields

    TRefCountedPtr<DependencyObject> m_pContainer;
    unsigned int m_flags;
    TRefCountedPtr<Object> m_pKey;
    TRefCountedPtr<ResourceDictionaryList> m_newDictionaries;
    TRefCountedPtr<ResourceDictionaryList> m_oldDictionaries;

#pragma endregion Private Fields
};

class ResourcesChangedEventArgs : public EventArgs
{
public:
#pragma region Internal Methods
    ResourcesChangedEventArgs(ResourcesChangeInfo info) : m_info(info) { }
#pragma endregion Internal Methods

#pragma region Internal Properties
    ResourcesChangeInfo get_Info() { return m_info; }
#pragma endregion Internal Properties

private:
#pragma region Private Fields
    ResourcesChangeInfo m_info;
#pragma endregion Private Fields
};

DEFINE_EVENTHANDLER(ResourcesChanged);



};
